package cn.osworks.aos.core.excel;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFCellStyle;
import org.apache.poi.hssf.usermodel.HSSFFont;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;

import cn.osworks.aos.core.asset.AOSUtils;
import cn.osworks.aos.core.typewrap.Dto;
import cn.osworks.aos.core.typewrap.impl.HashDto;

/**
 * desc:用POI操作EXCEL文件
 * 
 * @author gaol
 * 
 */
public class POIExcelUtil {
	// 一个sheet最大的行数
	private static final int mostColumn = 40000;
	private static Log log = LogFactory.getLog(POIExcelUtil.class);

	/**
	 * HSSFWorkbook:是操作Excel2003以前（包括2003）的版本，扩展名是.xls
	 * 
	 * @param is
	 */
	public static List<Dto> processOne(InputStream is, String[] param) throws Exception {
		List<Dto> list = new ArrayList<Dto>();
		/** Excel文件的存放位置。注意是正斜线 */
		// 创建对Excel工作簿文件的引用
		HSSFWorkbook workbook = new HSSFWorkbook(is);
		// 创建对工作表的引用。
		HSSFSheet sheet = workbook.getSheetAt(0);
		HSSFRow row_0 = sheet.getRow(0);

		int validColNum = 0;
		for (int i = (int) row_0.getLastCellNum() - 1; i >= 0; i--) {
			if (AOSUtils.isNotEmpty(row_0.getCell(i).toString())) {
				validColNum++;
			};
		}
		if (validColNum != param.length) {
			// throw new RuntimeException("不合法的excel模板");
		}
		// 也可用getSheetAt(int index)按索引引用，
		// 在Excel文档中，第一张工作表的缺省索引是0，
		for (int i = 1; i <= sheet.getLastRowNum(); i++) {
			if (null != sheet.getRow(i)) {
				Dto dto2 = new HashDto();
				HSSFRow row = sheet.getRow(i);
				for (int j = 0; j < param.length; j++) {
					// if (row.getCell(j) == null) {
					// dto2.put(param[j], "");
					// } else {
					// 读取数据类型的列
					if (row.getCell(j) != null && row.getCell(j).getCellType() == HSSFCell.CELL_TYPE_NUMERIC) {
						dto2.put(param[j], row.getCell(j) == null ? "" : row.getCell(j).getNumericCellValue());
					} else {
						dto2.put(param[j], row.getCell(j) == null ? "" : row.getCell(j).toString());
					}
					// }
					// dto2.put(param[j], row.getCell(j) == null ? "" : row
					// .getCell(j).toString());

				}
				list.add(dto2);
				// for (int j = 0; j < row.getLastCellNum(); j++) {
				// System.out.println(row.getCell(j));
				// }
			}
		}
		// System.out.println("左上端单元是： " + cell.getStringCellValue());
		return list;
	}

//	/**
//	 * XSSFWorkbook:是操作Excel2007的版本，扩展名是.xlsx
//	 * 
//	 * @param is
//	 */
//	public static List<BaseDto> processTwo(InputStream is, String[] param) throws Exception {
//		List<BaseDto> list = new ArrayList<BaseDto>();
//		XSSFWorkbook workbook = new XSSFWorkbook(is);
//		XSSFSheet st = workbook.getSheetAt(0);
//		for (int rowNumOfSheet = 1; rowNumOfSheet <= st.getLastRowNum(); rowNumOfSheet++) {
//			if (null != st.getRow(rowNumOfSheet)) {
//				BaseDto dto2 = new BaseDto();
//				XSSFRow row = st.getRow(rowNumOfSheet); // 获得一个行
//				// for (int i = 0; i < row.getLastCellNum(); i++) {
//				for (int i = 0; i < param.length; i++) {
//					//System.out.println(getCellString(row.getCell(i)));
//					dto2.put(param[i], row.getCell(i) == null ? "" : getCellString(row.getCell(i)));
//				}
//				// }
//				list.add(dto2);
//			}
//		}
//		return list;
//	}

//	public static String getCellString(XSSFCell cell) {
//		switch (cell.getCellType()) {
//		case HSSFCell.CELL_TYPE_NUMERIC: // 数字
//			return Math.round(cell.getNumericCellValue()) + "";
//		case HSSFCell.CELL_TYPE_STRING: // 字符串
//			return cell.getStringCellValue() + "";
//		case HSSFCell.CELL_TYPE_BOOLEAN: // Boolean
//			return cell.getBooleanCellValue() + "";
//		case HSSFCell.CELL_TYPE_FORMULA: // 公式
//			return cell.getCellFormula() + "";
//		case HSSFCell.CELL_TYPE_BLANK: // 空值
//			return "";
//		case HSSFCell.CELL_TYPE_ERROR: // 故障
//			return "";
//		default:
//			return "";
//		}
//	}
	
	public static String getCellString(HSSFCell cell) {
		switch (cell.getCellType()) {
		case HSSFCell.CELL_TYPE_NUMERIC: // 数字
			return cell.getNumericCellValue() + "";
		case HSSFCell.CELL_TYPE_STRING: // 字符串
			return cell.getStringCellValue() + "";
		case HSSFCell.CELL_TYPE_BOOLEAN: // Boolean
			return cell.getBooleanCellValue() + "";
		case HSSFCell.CELL_TYPE_FORMULA: // 公式
			return cell.getCellFormula() + "";
		case HSSFCell.CELL_TYPE_BLANK: // 空值
			return "";
		case HSSFCell.CELL_TYPE_ERROR: // 故障
			return "";
		default:
			return "";
		}
	}

	/**
	 * HSSFWorkbook:是操作Excel2003以前（包括2003）的版本，扩展名是.xls
	 * XSSFWorkbook:是操作Excel2007的版本，扩展名是.xlsx
	 * 
	 * @param is
	 */
	public static List<Dto> readExcel(InputStream is, String filename, String[] param) throws Exception {
//		if (filename.endsWith("x")) {
//			//return processTwo(is, param);
//		} else {
//			return processOne(is, param);
//		}
		return processOne(is, param);

	}

	/**
	 * desc:创建工作薄,扩展名只能是.xls考虑到兼容性问题不需要创建.xlsx
	 * 
	 * @param filename
	 *            文件的名称
	 * @param list
	 *            结果集合
	 * @param param
	 *            EXCEL 的首行标题集合
	 * @param valueIndex
	 *            basedto 的key值集合
	 * @return 文件输入量
	 */
	public static InputStream create(String filename, List<Dto> list, String[] param, String[] valueIndex) {
		HSSFWorkbook wb = new HSSFWorkbook();
		HSSFSheet sheet = null;
		// 设置单元格的样式
		HSSFFont font = wb.createFont();
		font.setColor(HSSFFont.COLOR_RED);
		font.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);
		HSSFCellStyle cellStyle = wb.createCellStyle();
		cellStyle.setFont(font);
		int rowIndex = 0;
		int cellIndex = 0;
		HSSFRow row = null;
		HSSFCell cell = null;
		sheet = wb.createSheet("sheet" + 1);
		row = sheet.createRow(rowIndex++);
		cell = row.createCell(cellIndex++);
		cell.setCellValue("序号");
		cell.setCellStyle(cellStyle);
		// 头信息
		for (int i = 0; i < param.length; i++) {
			cell = row.createCell(cellIndex++);
			cell.setCellValue(param[i]);
			cell.setCellStyle(cellStyle);
		}
		for (int i = 0; i < list.size(); i++) {  //输入表
			// excel每个sheet行数不得超过62265行
			if (i % mostColumn == 0 && i != 0) {
				sheet = null;
				rowIndex = 0;
				cellIndex = 0;
				sheet = wb.createSheet("sheet" + (i / mostColumn + 1));
				row = sheet.createRow(rowIndex++);
				cell = row.createCell(cellIndex++);
				cell.setCellValue("序号");
				cell.setCellStyle(cellStyle);
				// 头信息
				for (int j = 0; j < param.length; j++) {
					cell = row.createCell(cellIndex++);
					cell.setCellValue(param[j]);
					cell.setCellStyle(cellStyle);
				}
			}
			// 根据结果集合的信息遍历字段组建单元格
			cellIndex = 0;
			Dto dto = (Dto) list.get(i);
			row = sheet.createRow(rowIndex++);
			cell = row.createCell(cellIndex++);
			cell.setCellValue(i + 1);
			for (int j = 0; j < valueIndex.length; j++) {
				cell = row.createCell(cellIndex++);
				cell.setCellValue(dto.getString(valueIndex[j]));
			}
		}
		// 写入一个零时文件,并且把文件输入流传给ACTION
		File file = new File(filename);
		OutputStream os;
		try {
			os = new FileOutputStream(file);
			wb.write(os);
			os.flush();
			os.close();
			InputStream is = new FileInputStream(file);
			list = null;
			return is;
		} catch (Exception e) {
			e.printStackTrace();
		}

		return null;
	} 
}
